home *** CD-ROM | disk | FTP | other *** search
- /* slutty.c --- Unix Low level terminal (tty) functions for S-Lang */
- /* Copyright (c) 1992, 1995 John E. Davis
- * All rights reserved.
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Perl Artistic License.
- */
-
- #include <config.h>
- #include <stdio.h>
- #include <signal.h>
- /* sequent support thanks to Kenneth Lorber <keni@oasys.dt.navy.mil> */
- /* SYSV (SYSV ISC R3.2 v3.0) provided by iain.lea@erlm.siemens.de */
-
- #ifndef sequent
- # include <stdlib.h>
- #endif
- #include <sys/time.h>
- #ifndef sequent
- # include <unistd.h>
- # include <termios.h>
- #endif
-
- #ifdef SYSV
- # ifndef CRAY
- # include <sys/termio.h>
- # include <sys/stream.h>
- # include <sys/ptem.h>
- # include <sys/tty.h>
- # endif
- #endif
-
- #ifndef sun
- #include <sys/ioctl.h>
- #endif
-
- #ifdef __QNX__
- #include <sys/select.h>
- #endif
-
- #ifdef IS_AIX
- #include <sys/select.h>
- #endif
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
-
- #include "slang.h"
- #include "_slang.h"
-
- #define TTY_DESC 2
- int SLang_TT_Read_FD = TTY_DESC;
- int SLang_TT_Baud_Rate;
-
- static int Baud_Rates[20] =
- {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 0, 0, 0, 0
- };
-
-
-
- #ifdef sequent
- typedef struct
- {
- struct tchars t;
- struct ltchars lt;
- struct sgttyb s;
- }
- TTY_Termio_Type;
- #else
- typedef struct termios TTY_Termio_Type;
- #endif
-
- TTY_Termio_Type Old_TTY;
-
- /* this next works on ultrix for setting termios */
- #ifdef TCGETS
- #define GET_TERMIOS(fd, x) ioctl(fd, TCGETS, x)
- #define SET_TERMIOS(fd, x) ioctl(fd, TCSETS, x)
- #else
- # ifdef sequent
- # define X(x,m) &(((TTY_Termio_Type *)(x))->m)
- # define GET_TERMIOS(fd, x) \
- ioctl(fd, TIOCGETC, X(x,t));\
- ioctl(fd, TIOCGLTC, X(x,lt));\
- ioctl(fd, TIOCGETP, X(x,s))
- # define SET_TERMIOS(fd, x) \
- ioctl(fd, TIOCSETC, X(x,t));\
- ioctl(fd, TIOCSLTC, X(x,lt));\
- ioctl(fd, TIOCSETP, X(x,s))
- # else
- # define GET_TERMIOS(fd, x) tcgetattr(fd, x)
- # define SET_TERMIOS(fd, x) tcsetattr(fd, TCSAFLUSH, x)
- /* # define SET_TERMIOS(fd, x) tcsetattr(fd, TCSANOW, x) */
- # endif
- #endif
-
- static int TTY_Inited = 0;
-
- int SLang_init_tty (int abort_char, int no_flow_control, int opost)
- {
- TTY_Termio_Type newtty;
-
- if (TTY_Inited) return 0;
-
- SLang_Abort_Char = abort_char;
- SLang_TT_Read_FD = fileno (stdin);
- GET_TERMIOS(SLang_TT_Read_FD, &Old_TTY);
- GET_TERMIOS(SLang_TT_Read_FD, &newtty);
- #ifdef sequent
- newtty.s.sg_flags &= ~(ECHO);
- newtty.s.sg_flags &= ~(CRMOD);
- /* if (Flow_Control == 0) newtty.s.sg_flags &= ~IXON; */
- newtty.t.t_eofc = 1;
- newtty.t.t_intrc = SLang_Abort_Char; /* ^G */
- newtty.t.t_quitc = 255;
- newtty.lt.t_suspc = 255; /* to ignore ^Z */
- newtty.lt.t_dsuspc = 255; /* to ignore ^Y */
- newtty.lt.t_lnextc = 255;
- newtty.s.sg_flags |= CBREAK; /* do I want cbreak or raw????? */
- #else
-
- /* get baud rate */
-
- newtty.c_iflag &= ~(ECHO | INLCR | ICRNL);
- #ifdef ISTRIP
- newtty.c_iflag &= ~ISTRIP;
- #endif
- if (opost == 0) newtty.c_oflag &= ~OPOST;
-
- if (SLang_TT_Baud_Rate == 0)
- {
- /* Note: if this generates an compiler error, simply remove
- the statement */
- #ifdef HAVE_CFGETOSPEED
- SLang_TT_Baud_Rate = cfgetospeed (&newtty);
-
-
- SLang_TT_Baud_Rate = ((SLang_TT_Baud_Rate > 0) && (SLang_TT_Baud_Rate < 19)
- ? Baud_Rates[SLang_TT_Baud_Rate]
- : 0);
- #endif
- }
-
- if (no_flow_control) newtty.c_iflag &= ~IXON; else newtty.c_iflag |= IXON;
-
- newtty.c_cc[VMIN] = 1;
- newtty.c_cc[VTIME] = 0;
- newtty.c_cc[VEOF] = 1;
- newtty.c_lflag = ISIG | NOFLSH;
- newtty.c_cc[VINTR] = SLang_Abort_Char; /* ^G */
- newtty.c_cc[VQUIT] = 255;
- newtty.c_cc[VSUSP] = 255; /* to ignore ^Z */
- #ifdef VSWTCH
- newtty.c_cc[VSWTCH] = 255; /* to ignore who knows what */
- #endif
- #endif /*sequent*/
- SET_TERMIOS(SLang_TT_Read_FD, &newtty);
- TTY_Inited = 1;
- return 0;
- }
-
- void SLtty_set_suspend_state (int mode)
- {
- TTY_Termio_Type newtty;
- GET_TERMIOS (SLang_TT_Read_FD, &newtty);
- #ifdef sequent
- if (mode == 0) newtty.lt.t_suspc = 255;
- else newtty.lt.t_suspc = Old_TTY.lt.t_suspc;
- #else
- if (mode == 0) newtty.c_cc[VSUSP] = 255;
- else newtty.c_cc[VSUSP] = Old_TTY.c_cc[VSUSP];
- #endif
- SET_TERMIOS (SLang_TT_Read_FD, &newtty);
- if (TTY_Inited == 0) return;
- }
-
- void SLang_reset_tty (void)
- {
- if (!TTY_Inited) return;
- SET_TERMIOS(SLang_TT_Read_FD, &Old_TTY);
- TTY_Inited = 0;
- }
-
- #ifdef __cplusplus
- # define SIGNAL(a,b) signal((a), (SIG_PF)(b))
- #else
- # define SIGNAL signal
- #endif
-
- static void default_sigint (int sig)
- {
- SLKeyBoard_Quit = 1;
- if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
- SIGNAL (SIGINT, default_sigint);
- }
-
- void SLang_set_abort_signal (void (*hand)(int))
- {
- if (hand == NULL) hand = default_sigint;
- SIGNAL (SIGINT, hand);
- }
-
- #ifndef FD_SET
- #define FD_SET(fd, tthis) *(tthis) = 1 << fd
- #define FD_ZERO(tthis) *(tthis) = 0
- typedef int fd_set;
- #endif
-
- static fd_set Read_FD_Set;
-
-
- int SLsys_input_pending(int tsecs)
- {
- struct timeval wait;
- long usecs, secs;
- int ret;
-
- secs = tsecs / 10;
- usecs = (tsecs % 10) * 100000;
- wait.tv_sec = secs;
- wait.tv_usec = usecs;
-
- FD_ZERO(&Read_FD_Set);
- FD_SET(SLang_TT_Read_FD, &Read_FD_Set);
- ret = select(SLang_TT_Read_FD + 1, &Read_FD_Set, NULL, NULL, &wait);
- return (ret);
- }
-
-
- unsigned int SLsys_getkey (void)
- {
- int count = 10; /* number of times to retry if read fails */
- unsigned char c;
-
- while ((SLKeyBoard_Quit == 0)
- && !SLsys_input_pending(100));
-
- while (count-- && !SLKeyBoard_Quit && (read(SLang_TT_Read_FD, (char *) &c, 1) < 0)) sleep(1);
-
- if (count <= 0)
- {
- return 0xFFFF;
- }
-
- /* only way for keyboard quit to be non zero is if ^G recived and sigint processed */
- if (SLKeyBoard_Quit) c = SLang_Abort_Char;
- SLKeyBoard_Quit = 0;
- return((unsigned int) c);
- }
-